/**
 * 
 */
package resources;



import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Vector;
import java.util.logging.Level;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.sun.org.apache.xml.internal.serialize.LineSeparator;
import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

/**
 * @author pdrabik
 *
 */
public class XMLworker {
	
	private static final org.slf4j.Logger log = LoggerFactory.getLogger(XMLworker.class);
	
	private static String path = "D:/tempcii.xml";

	public static String createConfigXMLModel(String name, String[] elements) {
		try {
			DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			Document doc = builder.newDocument();
			Element root = doc.createElement("ConfigElement");
			root.setAttribute("type",name);
			for (int i=0;i<elements.length;i++) {
				Element el = doc.createElement("element");
				el.setTextContent(elements[i].toUpperCase());
				root.appendChild(el);
				el=null;
			}
//			log.debug(root.getAttribute("type"));
			doc.appendChild(root);
//			log.debug("-" + root.getFirstChild().getTextContent());
//			writeXmlFile(doc, new File("D:/t.xml"));
			return xmlToString(doc);
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			log.error("", e);
		}
		return "";
	}
	
	/**
	 * 
	 * @param doc
	 * @param file It is allowed for this parameter to be null. If so, setPath must be previously 
	 * configured
	 * @return
	 */
	public static boolean writeXmlFile(Document doc, File file) {
		try {
			OutputFormat format = new OutputFormat(doc, "UTF-8", false);
			format.setLineSeparator(LineSeparator.Windows);
			// format.setIndenting(true);
			format.setLineWidth(0);
			format.setPreserveSpace(true);
			OutputStreamWriter writer;
			if (file!=null) {
			writer = new OutputStreamWriter(
					new FileOutputStream(file), "UTF-8");
			} else {
				writer = new OutputStreamWriter(
						new FileOutputStream(new File(path)), "UTF-8");	
			}
			XMLSerializer serializer = new XMLSerializer(writer, format);
			serializer.asDOMSerializer();
			serializer.serialize(doc);
			writer.close(); // this also flushes
			return true;
		} catch (Exception ex) {
			log.error("Exception thrown in writeXmlFile(Document doc, String filename)", ex);
		}
		return false;
	}
	
	public static String xmlToString(Node node) {
		try {
			Source source = new DOMSource(node);
			StringWriter stringWriter = new StringWriter();
			Result result = new StreamResult(stringWriter);
			TransformerFactory factory = TransformerFactory.newInstance();
			Transformer transformer = factory.newTransformer();
			transformer.transform(source, result);
			return stringWriter.getBuffer().toString();
		} catch (TransformerConfigurationException e) {
			log.error("", e);
		} catch (TransformerException e) {
			log.error("", e);
		}
		return null;
	}
	
	public static Document parseString(String xmltoparse) {
		try {

			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			dbf.setValidating(false);
			DocumentBuilder builder;
			builder = dbf.newDocumentBuilder();
			return builder.parse(new InputSource(new StringReader(xmltoparse)));
		} catch (Exception e) {
			log.error("Error parsing", e);
		}
		
		return null;
	}
	
	public static Document parseXmlFile(String str) throws IllegalArgumentException {
		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder;

			builder = dbf.newDocumentBuilder();

			return builder.parse(str);

		} catch (SAXException e) {
			log.error("Parsing of xml file failed (send badfile.xml to a dev for analysis) - "
					+ "File name: '" + str + "'", e);
			// A parsing error occurred; the xml input is not valid
			
			throw new IllegalArgumentException();
		} catch (ParserConfigurationException e) {
			log.error("Exception thrown in parseXmlFile(File file, boolean validating) - "
					+ "File name: '" + str + "'", e);
		} catch (IOException e) {
			log.error("Exception thrown in parseXmlFile(File file, boolean validating) - "
					+ "File name: '" + str + "'", e);
		}
		return null;
	}
	
	public static Vector<String> parseXMLtoElements(String xml) {
		Document doc = parseString(xml);
		Vector<String> temp = new Vector<String>();
		NodeList elems = doc.getFirstChild().getChildNodes();
		for (int i=0;i<elems.getLength();i++) {
			temp.add(i, elems.item(i).getTextContent());
//			log.debug("e "+elems.item(i).getTextContent());
		}
		return temp;
	}

	/**
	 * @return the path
	 */
	public static String getPath() {
		return path;
	}

	/**
	 * @param path the path to set
	 */
	public static void setPath(String path) {
		XMLworker.path = path;
	}
	
}
